package com.xadrez.modelo;

import java.util.ArrayList;
import java.util.List;

public class Peao extends Peca {

    private boolean primeiroMovimento;

    public Peao() {
    }

    public Peao(Jogador jogador, Tabuleiro tabuleiro) {
        super(jogador, tabuleiro);
        primeiroMovimento = true;
    }

    @Override
    public List<Posicao> recuperaMovimentosPossiveis() {
        //Primeiro recuperamos a posição da casa onde se encontra a peca.
        int posicaoX = this.getPosicaoNoTabuleiro().getX();
        int posicaoY = this.getPosicaoNoTabuleiro().getY();

        List<Posicao> lista = new ArrayList<Posicao>();

        //O tipo de movimento varia de acordo com o jogador... Para cima ou para baixo...
        int x = posicaoX + 1;
        int xDobrado = posicaoX + 2;
        if (getTabuleiro().getJogadorDaVez().equals(getTabuleiro().getJogadorUm())) {
            x = posicaoX - 1;
            xDobrado = posicaoX - 2;
        }


        //Verifica se (x,y) é uma posição legal para mover.
        if (primeiroMovimento) {
            if (!getTabuleiro().temPecaDoJogadorNaPosicao(x, posicaoY, getJogador())
                    && !getTabuleiro().temAdversarioNaPosicao(x, posicaoY)
                    && !deixaReiEmCheck(new Posicao(x, posicaoY))) {
                lista.add(new Posicao(x, posicaoY));
            }
            if (!getTabuleiro().temPecaDoJogadorNaPosicao(x, posicaoY, getJogador())
                    && !getTabuleiro().temAdversarioNaPosicao(x, posicaoY)
                    && !getTabuleiro().temPecaDoJogadorNaPosicao(xDobrado, posicaoY, getJogador())
                    && !getTabuleiro().temAdversarioNaPosicao(xDobrado, posicaoY)
                    && !deixaReiEmCheck(new Posicao(xDobrado, posicaoY))) {
                lista.add(new Posicao(xDobrado, posicaoY));
            }
            if (getTabuleiro().temAdversarioNaPosicao(x, posicaoY - 1)
                    && !deixaReiEmCheck(new Posicao(x, posicaoY - 1))) {
                lista.add(new Posicao(x, posicaoY - 1));
            }
            if (getTabuleiro().temAdversarioNaPosicao(x, posicaoY + 1)
                    && !deixaReiEmCheck(new Posicao(x, posicaoY + 1))) {
                lista.add(new Posicao(x, posicaoY + 1));
            }
        } else {
            if (!getTabuleiro().temPecaDoJogadorNaPosicao(x, posicaoY, getJogador())
                    && !getTabuleiro().temAdversarioNaPosicao(x, posicaoY)
                    && !deixaReiEmCheck(new Posicao(x, posicaoY))) {
                lista.add(new Posicao(x, posicaoY));
            }
            if (getTabuleiro().temAdversarioNaPosicao(x, posicaoY - 1)
                    && !deixaReiEmCheck(new Posicao(x, posicaoY - 1))) {
                lista.add(new Posicao(x, posicaoY - 1));
            }
            if (getTabuleiro().temAdversarioNaPosicao(x, posicaoY + 1)
                    && !deixaReiEmCheck(new Posicao(x, posicaoY + 1))) {
                lista.add(new Posicao(x, posicaoY + 1));
            }
        }

        return lista;
    }

    @Override
    public List<Posicao> recuperaMovimentosParaCheck() {
        //Primeiro recuperamos a posição da casa onde se encontra a peca.
        int posicaoX = this.getPosicaoNoTabuleiro().getX();
        int posicaoY = this.getPosicaoNoTabuleiro().getY();

        List<Posicao> lista = new ArrayList<Posicao>();
        Posicao posicaoDoReiAdversario = getTabuleiro().getJogadorAdversario(getJogador()).getReiDoJogador().getPosicaoNoTabuleiro();

        if (getJogador().getId() == 1) {
            if (isPosicaoDentroDosLimites(new Posicao(posicaoX - 1, posicaoY + 1))
                    && posicaoDoReiAdversario.equals(new Posicao(posicaoX - 1, posicaoY + 1))) {
                lista.add(new Posicao(posicaoX - 1, posicaoY + 1));
            } else if (isPosicaoDentroDosLimites(new Posicao(posicaoX - 1, posicaoY - 1))
                    && posicaoDoReiAdversario.equals(new Posicao(posicaoX - 1, posicaoY - 1))) {
                lista.add(new Posicao(posicaoX - 1, posicaoY - 1));
            }
        } else {
            if (isPosicaoDentroDosLimites(new Posicao(posicaoX + 1, posicaoY + 1))
                    && posicaoDoReiAdversario.equals(new Posicao(posicaoX + 1, posicaoY + 1))) {
                lista.add(new Posicao(posicaoX + 1, posicaoY + 1));
            } else if (isPosicaoDentroDosLimites(new Posicao(posicaoX + 1, posicaoY - 1))
                    && posicaoDoReiAdversario.equals(new Posicao(posicaoX + 1, posicaoY - 1))) {
                lista.add(new Posicao(posicaoX + 1, posicaoY - 1));
            }
        }

        if (lista != null && !lista.isEmpty()) {
            lista.add(getPosicaoNoTabuleiro());
        }

        return lista;
    }
    
    public List<Posicao> recuperaTodosOsMovimentos() {
        //Primeiro recuperamos a posição da casa onde se encontra a peca.
        int posicaoX = this.getPosicaoNoTabuleiro().getX();
        int posicaoY = this.getPosicaoNoTabuleiro().getY();

        List<Posicao> lista = new ArrayList<Posicao>();

        if (getJogador().getId() == 2) {
            if (isPosicaoDentroDosLimites(new Posicao(posicaoX - 1, posicaoY + 1))) {
                lista.add(new Posicao(posicaoX - 1, posicaoY + 1));
            }
            if (isPosicaoDentroDosLimites(new Posicao(posicaoX - 1, posicaoY - 1))) {
                lista.add(new Posicao(posicaoX - 1, posicaoY - 1));
            }            
        } else {
            if (isPosicaoDentroDosLimites(new Posicao(posicaoX + 1, posicaoY + 1))) {
                lista.add(new Posicao(posicaoX + 1, posicaoY + 1));
            }
            if (isPosicaoDentroDosLimites(new Posicao(posicaoX + 1, posicaoY - 1))) {
                lista.add(new Posicao(posicaoX + 1, posicaoY - 1));
            }
        }

        if (lista != null && !lista.isEmpty()) {
            lista.add(getPosicaoNoTabuleiro());
        }

        return lista;
    }

    public boolean upar() {
        if ((getJogador().getId() == 1) && (getPosicaoNoTabuleiro().getX() == 0)) {
            return true;
        } else if ((getJogador().getId() == 2) && (getPosicaoNoTabuleiro().getX() == 7)) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public String toString() {
        return "peao";
    }

    public boolean isPrimeiroMovimento() {
        return primeiroMovimento;
    }

    public void setPrimeiroMovimento(boolean primeiroMovimento) {
        this.primeiroMovimento = primeiroMovimento;
    }

    @Override
    public List<Posicao> caminhoAteOReiAdversario() {
        return new ArrayList<Posicao>();
    }
}
